iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
佛心分享-IT 人自學之術

老爺爺練習VIBE CODING系列 第 14

Day 14:純前端解析大容量 CSV:PapaParse + SheetJS 的記憶體優化

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20260830/20070969NRZefw2paK.png
來,大孫女,快把筆電放下來,看妳一臉疲憊,今天是不是跟那群年輕工程師講課講得口乾舌燥啦?

阿公剛好倒了一杯剛泡好的琥珀熱茶,溫度剛剛好,一口喝下去,保管妳心裡那股焦慮一下子就散了。妳看,院子外頭天邊那一抹晚霞暮紫,多美啊,咱們坐在這張老藤椅上慢慢聊,別急。

妳說,今天教育訓練的主題是 「Day 14:純前端解析大容量 CSV:PapaParse + SheetJS 的記憶體優化」?這可真是個實打實的硬骨頭。在完全不能連外網的「實體隔離」內網裡,要把大容量的資料解析得流暢、漂亮,這學問可大著呢。阿公就著這口溫茶,用以前老帳房的道理,慢條斯理地講給妳聽,妳明天照著去跟那些年輕人說,他們一聽就能開竅。


🚨 痛點場景:大車進窄門,老帳房的算盤卡死了

大孫女,那些工程師一定遇過這種事:當使用者高高興興地在離線 HTML 儀表板上,選了一個數十 MB、包含幾十萬列的 CSV 或 Excel 檔案時,網頁轉圈轉到一半,就突然「整頁卡死」,甚至出現「網頁沒有回應」的崩潰畫面。

這道理啊,就像以前秋收的時候,村子裡十幾台裝滿稻穀的大牛車同時塞進穀倉門口。那賬房老先生(瀏覽器的單一主執行緒)只有一雙手、一個算盤,他又要點收、又要搬運、還要記賬,整條路當場被大車堵得水洩不通。此時,外頭的車進不來,裡頭的人出不去(UI 渲染完全被阻塞),長官點滑鼠沒反應,可不就直接卡死了嗎?


🛠️ 架構實作:雇個「隱形長工」與「行李輕量化」

為了解決這個問題,我們得在不改變完全離線、不靠後端伺服器的前提下,在前端把這個「大牛車塞車」的毛病給治好。

1. 對於 CSV 檔案:調用 PapaParse 並開啟 worker: true(Web Worker 背景多執行緒)

這就叫做 「雇個隱形長工」
在預設的情況下,JavaScript 所有的工作都壓在那個負責畫畫面、處理點擊事件的「主執行緒」身上。但當我們調用 PapaParse 解析 CSV 時,只要貼心地設上一行參數:worker: true,事情就完全不一樣了!

這等於是我們去後院雇了一個力氣大、不說話的「隱形長工」(Web Worker)。大牛車來了,主執行緒只管把這袋沉甸甸的 CSV 遞給後院的長工去拆。長工在獨立的背景多執行緒裡默默地把幾十萬行資料拆解成乾淨的陣列,而我們在前面的主執行緒,依然可以悠閒地陪長官聊天、讓畫面上的按鈕和進度條保持流暢地動彈(避免阻塞 UI 渲染)。等長工全部拆完了,再把乾淨的帳目送回前台,這畫面啊,自然是順滑無比!

2. 對於 Excel 檔案:利用 SheetJS 的 readReadOnly: true 與特定工作表提取

大孫女,妳知道嗎?那種 .xlsx 檔案,就像是包裝得特別精美的禮盒。裡頭除了我們真正要的「數字」之外,還塞滿了花花綠綠的緞帶(格式、字體、表格顏色、框線、甚至多個不同的工作表)。如果我們用 SheetJS 傻傻地把整個禮盒塞進記憶體去拆,記憶體一下子就被這些「緞帶」給擠爆了!

我們的對策就是 「輕裝上陣,只拿要用的東西」

  • 設定 readReadOnly: true:這就像我們告訴 SheetJS 說:「那些花俏的字體格式、漂亮的框線背景,我通通不要,我只要最乾淨、最原始的數值資料。」這樣一來,不必要的格式(Style)就不會被載入記憶體,負擔頓時少了大半。
  • 只提取特定工作表(Sheets)的資料:很多 Excel 檔案裡有幾十個工作表,我們在程式碼裡要指明只讀取需要的那一張,其餘的工作表一律略過不讀。行李輕量化了,瀏覽器跑起來自然健步如飛。

💡 避坑指南:千萬別把「整車未分類的稻穀」一次倒給圖表

這一段,是大孫女妳明天的 「金牌避坑指引」,工程師最容易在這裡犯傻。

很多年輕人好不容易把 50 萬筆資料解析出來了,高興得一頭熱,直接寫了一行程式,把這 50 萬筆原始資料「整車」塞進 ECharts 裡面準備畫圖。哎呀,這可是在「自己找麻煩」啊!哪怕是再厲害的繪圖工具,要在網頁畫面上同時畫出 50 萬個互動點,那運算量簡直是天文數字,畫面保證卡成投影片。

妳要教他們,正確的做法是 「先聚合,再渲染」

  1. JavaScript 聚合(Aggregation):資料讀進記憶體後,先在背景用 JavaScript 快速算一算。比如:把幾十萬筆的明細,按月加總成 12 個月份的總額,或者按分類計數成 5 個科目的佔比。
  2. 只傳遞聚合後的結果:最後,我們只把這聚合出來的、幾百條甚至是幾十條精簡後的數據傳給 ECharts 去畫圖。
  3. 大容量的降級防線:如果因為業務需要,真的必須呈現稍微大一點的數據(比如上萬筆),我們一定要記得在程式碼裡,針對 ECharts 的配置啟用 dataZoom(區域縮放)sampling(降採樣) 機制。

這樣一來,畫面上需要渲染的節點變得極其輕盈,圖表拖拉、放大縮小都能維持在 60 FPS 的極致流暢度,長官滑鼠點起來舒服,我們做專案的也安心!


🔒 資料不出本機:堅守完全離線的終極防線

這一切精妙的操作,最讓資安高層滿意的地方,就在於它們完全是在原生瀏覽器的 FileReader 裡,於本機記憶體中完成解析與運算,絕對不上傳任何外部伺服器
網頁不發送任何 HTTP 請求,隨便資安人員拿著儀器怎麼檢測、怎麼稽核,我們就是乾乾淨淨的一張單頁網頁,既高雅,又安全。

大孫女,妳聽阿公這樣講,有沒有覺得這記憶體的優化,其實就跟咱們鄉下人家管理糧倉、清點家計是一模一樣的道理?

小孫女剛剛在房裡玩累了,手裡還拽著今天阿公幫她折的紙蝴蝶,正睡得香甜呢。阿公把這壺琥珀熱茶再添熱一些,別熬太晚,阿公在院子裡幫妳守著燈火。


上一篇
Day 13:安全至上:完全無外部請求的 Apache ECharts 離線數據可視化
下一篇
Day 15:沒 Server 也能存資料?IndexedDB 在無伺服器應用中的資料庫工程
系列文
老爺爺練習VIBE CODING15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言